// 类编程
using System;
namespace ClassGrogramSpace
{
    class ClassGrogram
    {
        #region  字段（修饰符）7
        // public: 当你希望类外部的其他代码能够访问类的字段或方法时。
        public uint width = 123;

        // internal: 当你希望字段或方法只能在同一个程序集中被访问，但在程序集外部不可见时
        internal uint width = 123;

        // private : 当你希望字段或方法只能在其所属的类内部被访问时
        private uint width = 123;

        // protected: 当你希望字段或方法在其所属类以及派生类中能够被访问时
        public class BaseClass
        {
            protected int ProtectedField = 30;

            protected void ProtectedMethod()
            {
                Console.WriteLine("This is a protected method.");
            }
        }
        public class DerivedClass : BaseClass
        {
            public void ShowProtectedMember()
            {
                ProtectedField = 40; // 派生类中可以访问基类的受保护成员
                ProtectedMethod(); // 调用基类的受保护方法
            }
        }

        // static: 当你希望字段或方法属于类本身，而不是类的实例时.(优点：效率，方便，生命周期相同)，缺点：失去灵活性
        public class StaticExample
        {
            public static int StaticField = 50;

            public static void StaticMethod()
            {
                Console.WriteLine("This is a static method.");
            }
        }
        // 使用方式
        StaticExample.StaticMethod(); // 直接通过类名调用静态方法
        Console.WriteLine(StaticExample.StaticField); // 直接通过类名访问静态字段
        
        // readonly：当你希望字段在初始化之后就不能被修改时
        public class ReadOnlyExample
        {
            public readonly int ReadOnlyField;

            public ReadOnlyExample(int value)
            {
                ReadOnlyField = value; // 只能在构造函数中赋值
            }
        }
        // 使用方式
        ReadOnlyExample readOnlyExample = new ReadOnlyExample(60);
        // readOnlyExample.ReadOnlyField = 70; // 这行代码会编译错误，因为ReadOnlyField是只读的
        Console.WriteLine(readOnlyExample.ReadOnlyField); // 输出60

        // const 
        public class ConstExample
        {
            public const int ConstField = 80; // 必须在声明时就赋值，且必须是编译时常量

            public void ShowConstField()
            {
                Console.WriteLine(ConstField); // 可以访问常量字段
            }
        }
        // 使用方式
        ConstExample constExample = new ConstExample();
        constExample.ShowConstField(); // 输出80
        // ConstExample.ConstField = 90; // 这行代码会编译错误，因为ConstField是常量

        //override：表示成员重写了基类中的虚拟或抽象成员。
        //virtual：表示成员可以在派生类中被重写。
        //abstract：表示成员是抽象的，必须在派生类中被实现（对于方法）或赋值（对于属性）。
        class BaseClass
        {
            public virtual void DoSomething1()
            {
                Console.WriteLine("BaseClass implementation");
            }
            public abstract void DoSomething2();
        }
        class DerivedClass : BaseClass
        {
            public override void DoSomething1()
            {
                Console.WriteLine("DerivedClass implementation1");
            }
            public override void DoSomething1()
            {
                Console.WriteLine("DerivedClass implementation2");
            }
        }
        #endregion
        
        #region 属性
        // 属性可以说是字段的延伸,属性有两个核心的代码块,分别是get访问器和set访问器。设置属性的值时会执行set代码块，取属性的值时访问get代码块。set访问器设置不具有只读属性。属性和字段的访问方式是相同的。与字段不同的是属性不作为变量类分类，所以不能将属性作为ref参数和out参数传递。
        public int attributeValue{
            set;
            get;
        }
        #endregion

        #region 方法 
        // 无参数方法、有参方法、重载方法
        public class Cz
        {
            public void CzFun(){}
            public void CzFun(int x,int y){Console.WriteLine("{0}{1}",x,y);}
        }
        // Main()方法:返回类型void或者int,且必须为静态的
        static void Main(){}
        static void Main(string[] args){}
        static int Main(){}
        static int Main(string[] args){}
        // 构造方法 - 有参或者无参
        public class Gz
        {
            public Gz(){}
            public Gz(int x,int y){Console.WriteLine("{0}{1}",x,y);}
        }
        // 静态方法 - 静态成员存在于内存，静态成员不能访问非静态成员，非静态成员需要实例化才可以
        public class StaticExample
        {
            public static int StaticField = 50; // 静态成员不能访问非静态成员,所以使用static声明

            public static void StaticMethod()
            {
                Console.WriteLine("This is a static method：{0}",StaticField);
            }
        }
        // 析构方法：是在需要释放内存时自动执行的方法。通常不需要手动声明
        public class Xigou()
        {
            public Xigou(int x,int y)
            {
                Console.WriteLine("{0}{1}",x,y);
            }
            ~Xigou();
        }
        #endregion
    }
}